package com.amirarcane.lockscreen.ability;

import com.amirarcane.lockscreen.ResourceTable;
import com.amirarcane.lockscreen.andrognito.pinlockview.IndicatorDots;
import com.amirarcane.lockscreen.andrognito.pinlockview.PinLockListener;
import com.amirarcane.lockscreen.andrognito.pinlockview.PinLockView;
import com.amirarcane.lockscreen.util.Utils;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.IntentParams;
import ohos.agp.components.*;
import ohos.agp.text.Font;
import ohos.app.Context;
import ohos.data.DatabaseHelper;
import ohos.data.preferences.Preferences;
import java.io.*;
import java.util.Optional;


public class EnterPinAbility extends AbilitySlice {

    public static final String EXTRA_SET_PIN = "set_pin";
    public static final String EXTRA_Intent_SET_PIN = "intent_pin";
    public static final String EXTRA_FONT_TEXT = "textFont";
    public static final String EXTRA_Intent_FONT_TEXT = "intent_textFont";
    public static final String EXTRA_FONT_NUM = "numFont";
    public static final String EXTRA_intent_FONT_NUM = "intent_numFont";

    private static final int PIN_LENGTH = 4;

    private static final String PREFERENCES = "com.amirarcane.lockscreen";
    private static final String KEY_PIN = "pin";
    private static final String RAW_FILE_PATH = "entry/resources/rawfile/";

    private PinLockView mPinLockView;
    private IndicatorDots mIndicatorDots;
    private Text mTextTitle;
    private Text mTextAttempts;

    private boolean mSetPin = false;
    private String mFirstPin = "";

    public static Intent getIntent(Context context, boolean setPin) {

        Intent intent = new Intent();
        IntentParams in=new IntentParams();
        in.setParam("set_pin",setPin);
        intent.setParam("intent_pin",in);
        return intent;

    }

    public static Intent getIntent(Context context,String fontText, String fontNum) {

        Intent intent = new Intent();
        IntentParams in=new IntentParams();
        in.setParam("textFont",fontText);
        in.setParam("numFont",fontNum);

        intent.setParam("intent_pin",in);

        return intent;
    }

    public static Intent getIntent(Context context, boolean setPin, String fontText, String fontNum) {

      Intent intent = getIntent(context, fontText, fontNum);
      IntentParams intentTop = intent.getParam("intent_pin");
      if(intentTop != null )
      {
          intentTop.setParam("set_pin",setPin);
      }
      intent.setParam("intent_pin",intentTop);
      return intent;

    }

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        ComponentContainer rootLayout = (ComponentContainer) LayoutScatter.getInstance(this)
                .parse(ResourceTable.Layout_ability_enterpin, null, false);
        mTextAttempts = (Text) rootLayout.findComponentById(ResourceTable.Id_attempts);
        mTextTitle = (Text) rootLayout.findComponentById(ResourceTable.Id_title);
        mIndicatorDots = (IndicatorDots) rootLayout.findComponentById(ResourceTable.Id_indicator_dots);
        super.setUIContent(rootLayout);


        IntentParams test= intent.getParam("intent_pin");
        if(test != null) {
            mSetPin = test.hasParam("set_pin");
        }


        if (mSetPin) {
            changeLayoutForSetPin();
        } else {
            String pin = getPinFromSharedPreferences();
            if (pin.equals("")) {
                changeLayoutForSetPin();
                mSetPin = true;
            }
        }

        final PinLockListener pinLockListener = new PinLockListener() {

            @Override
            public void onComplete(String pin) {
                if (mSetPin) {
                    setPin(pin);
                } else {
                    checkPin(pin);
                }
            }

            @Override
            public void onEmpty() {
           System.out.println("pin is empty");
            }

            @Override
            public void onPinChange(int pinLength, String intermediatePin) {
                System.out.println("Pin changed, new length");
            }
        };

        mPinLockView = (PinLockView) findComponentById(ResourceTable.Id_pinlockView);
        mIndicatorDots = (IndicatorDots) findComponentById(ResourceTable.Id_indicator_dots);

        mPinLockView.attachIndicatorDots(mIndicatorDots);
        mPinLockView.setPinLockListener(pinLockListener);

        mPinLockView.setPinLength(PIN_LENGTH);

        mIndicatorDots.setIndicatorType(IndicatorDots.IndicatorType.FIXED);

        checkForFont(intent);
    }


    private void checkForFont(Intent intent) {

        IntentParams test= intent.getParam("intent_pin");
        if (test != null) {
            if (test.hasParam("textFont")) {

                String textfont = (String) test.getParam("textFont");
                Font T_font = getFont(getContext(), textfont, 3, false);
                setTextFont(T_font);
            }
            if (test.hasParam("numFont")) {

                String Numfont = (String) test.getParam("numFont");
                Font N_font = getFont(getContext(), Numfont, 3, false);
                setNumFont(N_font);
            }
        }
    }
    public static Font getFont(Context context, String fontId, int style, boolean italic) {
        final int BUFFER_LENGTH = 8192;
        final int DEFAULT_ERROR = -1;
        String fontFamily = fontId;
        String path = RAW_FILE_PATH + fontFamily;
        File file = new File(context.getDataDir(), fontFamily);
        try (OutputStream outputStream = new FileOutputStream(file);
             InputStream inputStream = context.getResourceManager().getRawFileEntry(path).openRawFile()) {
            byte[] buffer = new byte[BUFFER_LENGTH];
            int bytesRead = inputStream.read(buffer, 0, BUFFER_LENGTH);
            while (bytesRead != DEFAULT_ERROR) {
                outputStream.write(buffer, 0, bytesRead);
                bytesRead = inputStream.read(buffer, 0, BUFFER_LENGTH);
            }
        } catch (FileNotFoundException exception) {
        } catch (IOException exception) {
        }
        return Optional.of(new Font.Builder(file).setWeight(style/*Font.REGULAR*/).makeItalic(italic).build()).get();
    }

    private void setTextFont(Font sample) {
        try {

            mTextTitle.setFont(sample);
            mTextAttempts.setFont(sample);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void setNumFont(Font sample) {
        try {

          mPinLockView.setTypeFace(sample);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void setPin(String pin) {
        if (mFirstPin.equals("")) {
            mFirstPin = pin;
            mTextTitle.setText(ResourceTable.String_code_again);
            mPinLockView.resetPinLockView();
        } else {
            if (pin.equals(mFirstPin)) {
                writePinToSharedPreferences(pin);
               terminate();
            } else {
                mTextTitle.setText(ResourceTable.String_Pin_not_same);
                mPinLockView.resetPinLockView();
                mFirstPin = "";
            }
        }
    }


    private void writePinToSharedPreferences(String pin) {

        DatabaseHelper databasehelper = new DatabaseHelper(getContext());
        Preferences prefs = databasehelper.getPreferences(PREFERENCES);
        prefs.putString(KEY_PIN, Utils.sha256(pin)).flush();
    }

    private void checkPin(String pin) {
        if (Utils.sha256(pin).equals(getPinFromSharedPreferences())) {
            terminate();
        } else {

            mTextAttempts.setText(ResourceTable.String_Wrong_Pin);
            mPinLockView.resetPinLockView();

        }
    }

    private void changeLayoutForSetPin() {

       mTextAttempts.setVisibility(Component.INVISIBLE);
       mTextTitle.setText(ResourceTable.String_Set_Pin);
    }

    private String getPinFromSharedPreferences() {
        DatabaseHelper databasehelper = new DatabaseHelper(getContext());
        Preferences prefs = databasehelper.getPreferences(PREFERENCES);
        return prefs.getString(KEY_PIN, "");
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
    }
}
